#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdlib.h>
#include <assert.h>

#define NUM 10

typedef void (*func_t)(); //函数指针

func_t handlerTask[NUM];

//样例任务
void task1()
{
  printf("hander,task1\n");
}
void task2()
{
  printf("hander,task1\n");
}
void task3()
{
  printf("hander,task1\n");
}

void LoadTask()
{
    memset(handlerTask, 0,sizeof(handlerTask));
    handlerTask[0] = task1;
    handlerTask[1] = task2;
    handlerTask[2] = task3;

}


int main()
{
  pid_t id =fork();
  assert(id != -1);

  if(id == 0)
  {
    //child
    int cnt = 10;
    while(cnt)
    {
      printf("child running, pid: %d,ppid: %d,cnt :%d\n",getpid(),getppid(),cnt--);
      sleep(3);
      //int *p = 0;
      //*p = 100;//野指针问题
    }

    exit(10);
  }
  
  LoadTask();
  //parent
  int status = 0;
  while(1)
  {
    pid_t ret =waitpid(id, &status, WNOHANG);
    if(ret == 0)
    {
      //waitpid调用成功 && 子进程没退出
      //子进程没有退出，我的waitpid等待失败，仅仅是检测到了子进程没有退出
      printf("wait done ,but child is running...parent running other thingings\n");
      for(int i = 0;handlerTask[i] != NULL;++i)
      {
        handlerTask[i]();//采用回调的方式，执行我们想让父进程在空闲的时候知道
      }
    }
    else if(ret > 0)
    {
      //1.waitpid调用成功 && 子进程退出了
      printf("wait sucess, exit code:%d, sig: %d\n",(status>>8)&0xFF, status & 0x7F);
      break;
    }
    else 
    {
      //waitpid调用失败
      printf("wait call filed!\n");
      break;
    }
    sleep(1);
  }








  //parent
  //int status = 0;
  ////1.让OS释放子进程的僵尸状态
  ////2.获取子进程的退出结果
  ////在等待期间，子进程没有退出的时候，父进程只能阻塞等待
  //int ret =waitpid(id,&status,0);
  //if(ret > 0)
  //{
  //  //是否正常退出
  //  if(WIFEXITED(status))
  //  {
  //    //判断子进程运行结果是否OK
  //    printf("exit code: %d\n",WEXITSTATUS(status));
  //  }
  //  else
  //  {
  //    //TODO
  //    printf("child exit not normal!\n");
  //  }
  //  //printf("wait sucess, exit code:%d, sig: %d\n",(status>>8)&0xFF, status & 0x7F);
  //}
 
  return 0;
}
